package com.systemframework.exception;


import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.exception.NotPermissionException;
import cn.dev33.satoken.exception.NotRoleException;
import cn.hutool.json.JSONUtil;
import cn.zhxu.bs.SearchException;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import com.systemframework.enums.ResultCodeEnum;
import com.systemframework.util.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.sql.SQLSyntaxErrorException;


/**
 * @author summer
 * @date 2022-09-06 14:20
 */
@RestControllerAdvice
@Slf4j
public class GlobalExceptionControllerAdvice {

    @ExceptionHandler({ResultException.class})
    public Result<ResultException> resultException(ResultException exception){
        log.error("error msg:{}",exception.getMessage(),exception);
        if(JSONUtil.isTypeJSON(exception.getMessage())){
            JSONObject object = JSON.parseObject(exception.getMessage());
            return Result.errorResult(ResultCodeEnum.ERROR.code(),object);
        }
        return Result.errorResult(exception.getMessage());
    }

    @ExceptionHandler({SearchException.class})
    public Result<SearchException> searchExceptionResult(SearchException searchException){
        log.error("error msg:{}",searchException.getMessage(),searchException);
        return Result.errorResult(searchException.getMessage());
    }


    @ExceptionHandler({LicenseException.class})
    public Result<LicenseException> licenseExceptionResult(LicenseException licenseException){

        return Result.errorResult(ResultCodeEnum.LICENSE_EXIT_TIME);
    }


    /**
     * 空指针异常
     * @param
     * @return
     */
    @ExceptionHandler({NullPointerException.class})
    public Result<NullPointerException> nullException(NullPointerException e) {
        return Result.errorResult(ResultCodeEnum.NULL_POINTER_EXCEPTION);
    }

    /**
     * 订单抢购结束异常
     * @param abnormalException
     * @return
     */
    @ExceptionHandler({AbnormalException.class})
    public Result<AbnormalException> abnormalExceptionResult(AbnormalException abnormalException){
        log.error("error msg:{}",abnormalException.getMessage(),abnormalException);
        return Result.errorResult(ResultCodeEnum.ORDER_EXCEPTION.code(),abnormalException.getMessage());
    }


    /**
     * 数组下标越界
     * @param
     * @return
     */
    @ExceptionHandler({ArrayIndexOutOfBoundsException.class})
    public Result<ArrayIndexOutOfBoundsException> arrayIndexOutOfBoundsException(){
        return Result.errorResult(ResultCodeEnum.ARRAY_INDEX_OUT);
    }

    /**
     * 算术异常
     * @return
     */
    @ExceptionHandler({ArithmeticException.class})
    public Result<ArithmeticException> ae(){
        return Result.errorResult(ResultCodeEnum.BY_ZERO);
    }


    /**
     *  数字格式异常
     * @param
     * @return
     */
    @ExceptionHandler({NumberFormatException.class})
    public Result<NumberFormatException> numberFormatException(){
        return Result.errorResult(ResultCodeEnum.NUMBER);
    }

    /**
     * 类型转换异常
     * @param
     * @return
     */
    @ExceptionHandler({ClassCastException.class})
    public Result<ClassCastException> classCastException(){
        return Result.errorResult(ResultCodeEnum.CLASS_CAST);
    }

    /**
     * 参数异常
     * @param
     * @return
     */
    @ExceptionHandler({IllegalArgumentException.class})
    public Result<IllegalArgumentException> illegalArgumentException(){
        return Result.errorResult(ResultCodeEnum.ILLEGAL);
    }
    @ExceptionHandler(NotPermissionException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public Result<String> notPermissionException(NotPermissionException e){
        return Result.errorResult(ResultCodeEnum.ACCESS_UNAUTHORIZED);
    }



    @ExceptionHandler({BindException.class})
    public Result<BindException> bindException(BindException e){
        log.error("error:{}",e.getMessage(),e);
        String message = e.getBindingResult().getFieldError().getDefaultMessage();
        return Result.errorResult(message);
    }

    @ExceptionHandler({MethodArgumentNotValidException.class})
    public Result<MethodArgumentNotValidException>  methodArgumentNotValidExceptionResult(MethodArgumentNotValidException e){
        String defaultMessage = e.getBindingResult().getFieldError().getDefaultMessage();
        return Result.errorResult(defaultMessage);
    }


    @ExceptionHandler({SQLSyntaxErrorException.class})
    public Result<SQLSyntaxErrorException>  sqlSyntaxErrorExceptionResult(SQLSyntaxErrorException e){
        log.error("sqlSyntaxErrorExceptionResult:{}",e.getLocalizedMessage(),e);
        return Result.errorResult(ResultCodeEnum.SQL_EXCEPTION);
    }



    @ExceptionHandler({NotLoginException.class})
    public  Result<NotLoginException> notLoginException(NotLoginException e){
        String type = e.getType();
        ResultCodeEnum codeEnum = null;
        switch (type){
            case "-2":
                codeEnum=ResultCodeEnum.INVALID_TOKEN_MESSAGE;
                break;
            case "-3":
                codeEnum=ResultCodeEnum.TOKEN_TIMEOUT_MESSAGE;
                break;
            default:
                codeEnum=ResultCodeEnum.NOT_TOKEN_MESSAGE;
        }
        return Result.errorResult(codeEnum);
    }

    @ExceptionHandler({NotRoleException.class})
    public Result<NotRoleException> notRoleExceptionResult(NotRoleException e){
        return Result.errorResult(e.getMessage());
    }
}
